import http from '@ohos.net.http';
import logUtil from './LogUtil'

const TAG = 'NetworkUtil'

/**
 * 请求选项
 */
interface RequestOptions {
    // 业务名称
    businessName?: string
    // 请求地址
    url: string
    // 请求方式
    method?: 'POST' | 'GET'
    // 请求参数数据格式
    dataFormat?: 'FORM' | 'JSON'
    // 请求参数
    extraData?: Object
    // 请求头
    header?: Object
}

/**
 * 网络请求
 */
class NetworkUtil {
    private httpRequest: http.HttpRequest

    /**
     * 获取请求方式
     * @param methodStr 字符串类型
     */
    private getMethod(methodStr: string) {
        switch (methodStr) {
            case 'GET':
                return http.RequestMethod.GET
                break;
            case 'POST':
                return http.RequestMethod.POST
                break;
        }
    }

    /**
     * 网络请求
     * @param options 请求选项
     * @return Pormise 返回值为泛型对象
     */
    request<T>(options: RequestOptions): Promise<T> {
        if (!this.httpRequest) {
            logUtil.info(TAG, 'createHttp')
            this.httpRequest = http.createHttp()
        }
        // 参数格式没传，设置默认格式
        if (!options.dataFormat) {
            options.dataFormat = 'JSON'
        }
        // 没有设置请求方式，传参是POST，不传参GET
        if (!options.method) {
            // 请求方式根据是否传参决定
            options.method = options.extraData ? 'POST' : 'GET'
        }
        // 业务名称
        const businessName = options.businessName ? `${options.businessName}-` : ''
        logUtil.info(TAG, businessName + '请求链接：' + options.url)
        logUtil.info(TAG, businessName + '请求方式：' + options.method)
        // http请求对象
        const requestOptions: http.HttpRequestOptions = {
            // http请求方法
            method: this.getMethod(options.method)
        }
        // 公共Header
        const commonHeader = { 'token': '' }
        // 根据参数格式设置header Content-Type
        if (options.extraData) {
            logUtil.info(TAG, businessName + '请求参数：' + options.extraData)
            if (options.dataFormat === 'FORM') {
                // http请求header Content-Type = form表单数据格式
                commonHeader['Content-Type'] = 'application/x-www-form-urlencoded'
                let strParam = ""
                for (let key in options.extraData) {
                    if (strParam) {
                        strParam += '&' + key + '=' + options.extraData[key]
                    } else {
                        strParam += key + '=' + options.extraData[key]
                    }
                }
                // http请求参数：key=value & key1=value1
                requestOptions.extraData = strParam
            } else {
                // http请求header Content-Type = json数据格式（这是http框架默认值）
                commonHeader['Content-Type'] = 'application/json'
                // http请求参数：对象
                requestOptions.extraData = options.extraData
            }
        }
        // http设置header
        requestOptions.header = commonHeader
        logUtil.info(TAG, businessName + '请求Header：' + JSON.stringify(commonHeader))
        // 返回Promised对象
        return new Promise((resolve, reject) => {
            this.httpRequest.request(options.url, requestOptions, (err, data) => {
                if (err) {
                    logUtil.info(TAG, businessName + '响应失败：err = ' + JSON.stringify(err))
                    reject('request error : ' + JSON.stringify(err))
                    return
                }
                if (data.responseCode !== http.ResponseCode.OK) {
                    logUtil.info(TAG, businessName + '响应失败：responseCode = ' + data.responseCode + '，data = ' + JSON.stringify(data))
                    reject('request error : ' + data.responseCode)
                    return
                }

                let str = data.result.toString()
                let index = 0
                while (index < str.length) {
                    logUtil.info(TAG, businessName + '响应成功：' + str.substring(index, index + 500))
                    index += 500
                }
                // json字符串解析成对象
                const dataModel = JSON.parse(data.result.toString())
                if (dataModel.code === 200) {
                    resolve(dataModel.data)
                } else {
                    logUtil.info(TAG, businessName + '接口失败：code = ' + dataModel.code)
                    reject('request error : ' + dataModel.code)
                }
            })
        })
    }

    /**
     * 中断请求
     */
    destroy() {
        this.httpRequest.destroy()
    }
}

export default new NetworkUtil()